package com.moon.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.moon.annotations.DataSource;
import com.moon.mapper.EmpExprMapper;
import com.moon.mapper.EmpMapper;
import com.moon.pojo.*;
import com.moon.service.EmpLogService;
import com.moon.service.EmpService;
import com.moon.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private EmpExprMapper  empExprMapper;

    @Autowired
    private EmpLogService empLogService;
//    @Override
//    @DataSource("db02")
//    public PageResult<Emp> page(Integer page, Integer pageSize) {
////        Long total = empMapper.count();
////        int start = (page - 1) * pageSize;
////        List<Emp> rows = empMapper.page(start, pageSize);
//
//        PageHelper.startPage(page, pageSize);
//        List<Emp> emps = empMapper.pageWithPageHelper();
//
//        Page<Emp> empPage = (Page<Emp>) emps;
//        return new PageResult<>(empPage.getTotal(), empPage.getResult());
//    }

    @Override
    @DataSource("db02")
    public PageResult<Emp> page(EmpQueryParam empQueryParam) {
        log.info("-----------------------------db02----------------------");
        log.info(empQueryParam.toString());

        PageHelper.startPage(empQueryParam.getPage(), empQueryParam.getPageSize());

        List<Emp> emps = empMapper.pageWithPageHelperAndXml(empQueryParam);

        Page<Emp> empPage = (Page<Emp>) emps;
        return new PageResult<>(empPage.getTotal(), empPage.getResult());
    }

    @Override
    @DataSource("db02")
    @Transactional(rollbackFor = Exception.class)
    public void addEmp(Emp emp) {
        try {
            log.info("添加员工，参数：emp={}",emp);
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());
            empMapper.insert(emp);
//            if (true)
//                throw new RuntimeException("手动抛出异常");
            emp.getExprList().forEach(empExpr -> {
                empExpr.setEmpId(emp.getId());
            });
            empExprMapper.batchInsert(emp.getExprList());
        } finally {
            empLogService.insertLog(new EmpLog(null, LocalDateTime.now(), "添加员工" + emp));
        }

    }

    @Override
    @DataSource("db02")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteEmpByIds(List<Integer> ids) {
        empMapper.deleteByIds(ids);

        empExprMapper.deleteByEmpIds(ids);
    }

    @Override
    @DataSource("db02")
    public Emp getEmpById(Integer id) {
        return empMapper.getEmpById(id);
    }

    @Override
    @DataSource("db02")
    @Transactional(rollbackFor = Exception.class)
    public void updateEmp(Emp emp) {
        // 动态修改emp表
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.updateEmp(emp);

        //删除empExpr表的数据
        empExprMapper.deleteByEmpIds(Collections.singletonList(emp.getId()));

        // 插入empExpr表数据,需要为empExpr的empId赋值
        if (CollectionUtil.isNotEmpty(emp.getExprList())){
            emp.getExprList().forEach(empExpr -> {
                empExpr.setEmpId(emp.getId());
            });
            empExprMapper.batchInsert(emp.getExprList());
        }
    }

    @Override
    @DataSource("db02")
    public LoginInfo login(Emp emp) {
        Emp e = empMapper.selectOne(emp);
        if (e != null){
            log.info("员工登录成功，员工信息：{}", e);
            HashMap<String, Object> claims = new HashMap<>() {{
                put("id", e.getId());
                put("username", e.getUsername());
                put("name", e.getName());
            }};
            return new LoginInfo(e.getId(), e.getUsername(), e.getName(), JwtUtils.generateJwt(claims));
        }
        return null;
    }
}
